/**
 * 
 */
package com.jm.report.action;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.jsp.JspWriter;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.j2ee.servlets.ImageServlet;

import com.jm.report.datasource.BaseDataEntitiesJRDataSource;
import com.jm.report.datasource.ListJRDataSource;
import com.jm.report.datasource.MapJRDataSource;
import com.jm.report.datasource.ResultSetJRDataSource;
import com.jm.utils.StringHelper;
import com.jm.utils.Utils;
import com.jm.web.BasePage;
import com.jm.web.data.BaseDataEntities;
import com.jm.web.data.JMForm;
import com.jm.web.data.ReturnData;

/**
 * @author yanjie
 * Mar 1, 2012 9:37:51 AM
 */
public class ReportExportActionHelper {
	private BasePage page1 = null;
	JspWriter out = null;
	ReturnData ret = null;
	Utils utils = null;
	JMForm form = null;
	private String backimg = "";
	private boolean bbackPrint = true;
	
	

	private String reportType = "HTML";//報表類型
	private String reportPath = "";//報表文件路徑
	private boolean bBreakPage = false;
	
	
	public void init(BasePage page) {
		this.page1 = page;
		this.out = this.page1.getWriter();
		this.utils = this.page1.getUtils();
		this.form = utils.getForm();
		this.ret = utils.getReturnData();
	}
	
	public void Export () throws Exception{
		if("HTML".equalsIgnoreCase(this.getReportType())){
			this.ExportHtml();
			return;
		}else if("PDF".equalsIgnoreCase(this.getReportType())){
			this.ExportPdf();
			return;
		}
		return;
	}
	
	public void ExportHtml() throws Exception{
		this.getPage().getResponse().setContentType("text/html");
		out.clear();
		File reportFile = new File(this.getReportPath());
		JasperReport jasperReport = (JasperReport) JRLoader.loadObject(reportFile.getPath());
		JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,
					this.getParams(),
					getJRDataSource(ret.getSerchResult()));
		
		JRHtmlExporter exporter = new JRHtmlExporter();
		this.getPage().getRequest().getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,jasperPrint);
		exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
		exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);
		exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, this.getPage().getContextPath()+"/servlets/image?image=");
		exporter.setParameter(JRHtmlExporterParameter.CHARACTER_ENCODING, "UTF-8");
		
		if(this.isBreakPage())//是否需要強制換頁
			exporter.setParameter(JRHtmlExporterParameter.BETWEEN_PAGES_HTML, "<div style=\"page-break-after: always;height:1px;\" ></div>");
		exporter.exportReport();
		out.flush();
	}
	
	public void ExportPdf() throws Exception{
		String strTempPath  = this.getTempDataPath();
		JasperRunManager.runReportToPdfFile(this.getReportPath(),strTempPath, this.getParams(),
				getJRDataSource(ret.getSerchResult()));
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try
		{
			this.getPage().getResponse().reset();
			bis = new BufferedInputStream(new FileInputStream(strTempPath));
			bos = new BufferedOutputStream(this.getPage().getResponse().getOutputStream());

			byte[] buff = new byte[2048];
			int bytesRead;

			while (-1 != (bytesRead = bis.read(buff, 0, buff.length)))
			{
				bos.write(buff, 0, bytesRead);
			}

		}
		catch (final IOException e)
		{
			System.out.println("出现IOException." + e);
		}
		finally
		{
			if (bis != null)
				bis.close();
			if (bos != null)
				bos.close();
		}
	}
	
	public JRDataSource getJRDataSource(Object object){
		if(object == null)
			return null;
		
		if(object instanceof ResultSet)
			return new ResultSetJRDataSource((ResultSet)object);
		
		if(object instanceof BaseDataEntities)
			return new BaseDataEntitiesJRDataSource((BaseDataEntities)object);
		
		if(object instanceof List)
			return new ListJRDataSource((List)object);
		
		if(object instanceof Map)
			return new MapJRDataSource((Map)object);
		
		
		return null;
	}
	
	public String getTempDataPath(){
		this.getPage().getResponse().setContentType("application/pdf");
		String strTempPath  = utils.getTempDataPath()+utils.getHrNum()+".pdf";
		File file = new File(strTempPath);
		if(!file.getParentFile().exists())file.getParentFile().mkdirs();
		return strTempPath;
	}
	
	public Map getParams(){
		Map parameters = new TreeMap();
		parameters.put("page",page1);
		parameters.put("ret",ret);
		parameters.put("form",form);
		parameters.put("utils",utils);
		if(!StringHelper.IsNullOrEmpty(this.getBackimg()))
			parameters.put("backimg", this.getBackimg());
		parameters.put("backprint",this.isbackPrint());
		return parameters;
	}
	
	public BasePage getPage() {
		return page1;
	}

	public String getReportType() {
		return reportType;
	}

	public void setReportType(String reportType) {
		this.reportType = reportType;
	}

	public String getReportPath() {
		return reportPath;
	}

	public void setReportPath(String reportPath) {
		if(reportPath.startsWith("report/")){
			this.reportPath = this.getPage().getRequest().getRealPath(reportPath);
		}else{
			this.reportPath = this.getPage().getRequest().getRealPath("report/"+reportPath);
		}
	}

	public boolean isBreakPage() {
		return bBreakPage;
	}

	public void setBreakPage(boolean breakPage) {
		bBreakPage = breakPage;
	}
	
	public boolean isbackPrint() {
		return bbackPrint;
	}

	public void setbackPrint(boolean bbackPrint) {
		this.bbackPrint = bbackPrint;
	}

	public String getBackimg() {
		return backimg;
	}

	public void setBackimg(String backimg) {
		this.backimg = backimg;
	}
}
